package com.moj.nestedscrollwebview_master;

import android.content.Context;
import android.support.v4.view.MotionEventCompat;
import android.support.v4.view.NestedScrollingChild;
import android.support.v4.view.NestedScrollingChildHelper;
import android.support.v4.view.ViewCompat;
import android.util.AttributeSet;
import android.view.MotionEvent;
import android.webkit.WebView;

/**
 * Created by moj on 2017/8/25.
 */

public class NestedScrollWebView extends WebView implements NestedScrollingChild {

	public static final String TAG = NestedScrollWebView.class.getSimpleName();

	private int mLastMotionY;

	private final int[] mScrollOffset = new int[2];
	private final int[] mScrollConsumed = new int[2];

	private int mNestedYOffset;
	private boolean mChange;

	private NestedScrollingChildHelper mChildHelper;

	public NestedScrollWebView(Context context) {
		super(context);
		init();
	}

	public NestedScrollWebView(Context context, AttributeSet attrs) {
		super(context, attrs);
		init();
	}

	public NestedScrollWebView(Context context, AttributeSet attrs, int defStyleAttr) {
		super(context, attrs, defStyleAttr);
		init();
	}

	private void init() {
		mChildHelper = new NestedScrollingChildHelper(this);
		setNestedScrollingEnabled(true);
	}

	private float downx;
	private float downy;
	private MotionEvent b;
	@Override
	public boolean onTouchEvent(MotionEvent event) {
		boolean result = false;

		MotionEvent trackedEvent = MotionEvent.obtain(event);

		final int action = MotionEventCompat.getActionMasked(event);

		if (action == MotionEvent.ACTION_DOWN) {
			mNestedYOffset = 0;
		}

		int y = (int) event.getY();

		event.offsetLocation(0, mNestedYOffset);

		switch (action) {
			case MotionEvent.ACTION_DOWN:
				mLastMotionY = y;
				startNestedScroll(ViewCompat.SCROLL_AXIS_VERTICAL);
				result = super.onTouchEvent(event);
				mChange = false;
				downx = event.getX();
				downy = event.getY();
				b = MotionEvent.obtain(event);
				break;
			case MotionEvent.ACTION_MOVE:
				int deltaY = mLastMotionY - y;

				if (dispatchNestedPreScroll(0, deltaY, mScrollConsumed, mScrollOffset)) {
					deltaY -= mScrollConsumed[1];
					trackedEvent.offsetLocation(0, mScrollOffset[1]);
					mNestedYOffset += mScrollOffset[1];
				}

				int oldY = getScrollY();
				mLastMotionY = y - mScrollOffset[1];
				int newScrollY = Math.max(0, oldY + deltaY);
				deltaY -= newScrollY - oldY;
				if (dispatchNestedScroll(0, newScrollY - deltaY, 0, deltaY, mScrollOffset)) {
					mLastMotionY -= mScrollOffset[1];
					trackedEvent.offsetLocation(0, mScrollOffset[1]);
					mNestedYOffset += mScrollOffset[1];
				}
				if(mScrollConsumed[1]==0 && mScrollOffset[1]==0) {
					if(mChange){
						mChange =false;
						trackedEvent.setAction(MotionEvent.ACTION_DOWN);
						super.onTouchEvent(trackedEvent);
					}else {
						result = super.onTouchEvent(trackedEvent);
					}
					trackedEvent.recycle();
				}else{
					if(Math.abs(mLastMotionY - y) >= 10) {
						if (!mChange) {
							mChange = true;
							super.onTouchEvent(MotionEvent.obtain(0, 0, MotionEvent.ACTION_CANCEL, 0, 0, 0));
						}
					}

				}
				break;
			case MotionEvent.ACTION_POINTER_DOWN:
			case MotionEvent.ACTION_UP:
			case MotionEvent.ACTION_CANCEL:
				stopNestedScroll();
				result = super.onTouchEvent(event);
				break;
		}
		return result;
	}

	// NestedScrollingChild

	@Override
	public void setNestedScrollingEnabled(boolean enabled) {
		mChildHelper.setNestedScrollingEnabled(enabled);
	}

	@Override
	public boolean isNestedScrollingEnabled() {
		return mChildHelper.isNestedScrollingEnabled();
	}

	@Override
	public boolean startNestedScroll(int axes) {
		return mChildHelper.startNestedScroll(axes);
	}

	@Override
	public void stopNestedScroll() {
		mChildHelper.stopNestedScroll();
	}

	@Override
	public boolean hasNestedScrollingParent() {
		return mChildHelper.hasNestedScrollingParent();
	}

	@Override
	public boolean dispatchNestedScroll(int dxConsumed, int dyConsumed, int dxUnconsumed, int dyUnconsumed, int[] offsetInWindow) {
		return mChildHelper.dispatchNestedScroll(dxConsumed, dyConsumed, dxUnconsumed, dyUnconsumed, offsetInWindow);
	}

	@Override
	public boolean dispatchNestedPreScroll(int dx, int dy, int[] consumed, int[] offsetInWindow) {
		return mChildHelper.dispatchNestedPreScroll(dx, dy, consumed, offsetInWindow);
	}

	@Override
	public boolean dispatchNestedFling(float velocityX, float velocityY, boolean consumed) {
		return mChildHelper.dispatchNestedFling(velocityX, velocityY, consumed);
	}

	@Override
	public boolean dispatchNestedPreFling(float velocityX, float velocityY) {
		return mChildHelper.dispatchNestedPreFling(velocityX, velocityY);
	}

}